package mk.com.ldm.corepoint.implementation.client.presenter;

import java.util.ArrayList;
import java.util.LinkedList;

import mk.com.ldm.corepoint.implementation.client.CoreServiceAsync;
import mk.com.ldm.corepoint.implementation.client.event.NavigationEvent;
import mk.com.ldm.corepoint.implementation.client.lib.custom.cpstable.ActionEvent;
import mk.com.ldm.corepoint.implementation.client.lib.custom.cpstable.ActionEventHandler;
import mk.com.ldm.corepoint.implementation.client.lib.custom.cpstable.CustomPagingScrollTable;
import mk.com.ldm.corepoint.implementation.client.lib.generators.EditEvent;
import mk.com.ldm.corepoint.implementation.client.lib.generators.EditEventHandler;
import mk.com.ldm.corepoint.implementation.client.lib.generators.FormGenerator;
import mk.com.ldm.corepoint.implementation.client.view.MenuGenerator;
import mk.com.ldm.corepoint.implementation.client.view.ModalOverlay;
import mk.com.ldm.corepoint.implementation.client.view.WorkFlowView;
import mk.com.ldm.corepoint.implementation.client.view.EditView;
import mk.com.ldm.corepoint.implementation.shared.FormObject;
import mk.com.ldm.corepoint.implementation.shared.LoginData;
import mk.com.ldm.corepoint.implementation.shared.WorkFlowObject;

import org.gwt.mosaic.ui.client.InfoPanel;
import org.gwt.mosaic.ui.client.MessageBox;
import org.gwt.mosaic.ui.client.MessageBox.ConfirmationCallback;

import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Widget;

//TODO: MAIN MENU HANDLER, NAVIGATION
public class MainPresenter implements Presenter {
	public interface Display {
		void setForm(Widget form);

		Widget asWidget();

		HorizontalPanel getContent();
	}

	private final CoreServiceAsync rpcService;
	private final HandlerManager eventBus;
	private final Display display;
	private String type;
	private String objectName;
	private String name;

	private final FormGenerator formGenerator;
	private int start = 1;
	private String itemId;
	private String token;
	private MenuGenerator menuGenerator = new MenuGenerator();

//	
	private CustomPagingScrollTable table = new CustomPagingScrollTable();
//
	
	public MainPresenter(CoreServiceAsync rpcService, HandlerManager eventBus,
			Display view) {
		this.rpcService = rpcService;
		this.eventBus = eventBus;
		this.display = view;
		this.formGenerator = new FormGenerator(eventBus, null, "insert");
	}

	public MainPresenter(CoreServiceAsync rpcService, HandlerManager eventBus,
			Display view, String type, String objectName) {
		this.rpcService = rpcService;
		this.eventBus = eventBus;
		this.display = view;
		this.type = type;
		this.objectName = objectName;
		this.formGenerator = new FormGenerator(eventBus, null, "insert");
	}

	public MainPresenter(CoreServiceAsync rpcService, HandlerManager eventBus,
			Display view, String type, String objectName, String itemId) {
		this.rpcService = rpcService;
		this.eventBus = eventBus;
		this.display = view;
		this.type = type;
		this.itemId = itemId;
		this.objectName = objectName;
		this.formGenerator = new FormGenerator(eventBus, null, "update");
	}
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getToken() {
		return token;
	}

	public void setToken(String token) {
		this.token = token;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public String getObjectName() {
		return objectName;
	}

	public void setObjectName(String objectName) {
		this.objectName = objectName;
	}

	public void go(final HasWidgets container) {
		display.getContent().clear();

		if (LoginData.getInstance().getUsername() == null
				|| LoginData.getInstance().getHash() == null) {
			History.newItem("login");
		} else if (LoginData.getInstance().getUsername()
				.equals(Cookies.getCookie("username"))
				&& LoginData.getInstance().getHash()
						.equals(Cookies.getCookie("hash"))) {
			if (start == 1) {
				container.clear();
				container.add(display.asWidget());
				start = 0;
			}
			getContent();
		}

	}

	public void init(HasWidgets container) {
		container.add(display.asWidget());
	}

	public void getContent() {
		if (type.equals("WorkFlow")) {
			ModalOverlay.show();
			rpcService.parseWorkFlow(Cookies.getCookie("username"), objectName,
					type, name,
					new AsyncCallback<LinkedList<WorkFlowObject>>() {

						@Override
						public void onSuccess(LinkedList<WorkFlowObject> result) {
							WorkFlowPresenter wfp = new WorkFlowPresenter(
									rpcService, eventBus, new WorkFlowView(),
									result);
							display.getContent().clear();
							wfp.go(display.getContent());
							ModalOverlay.hide();
						}

						@Override
						public void onFailure(Throwable caught) {
							ModalOverlay.hide();
							InfoPanel.show("Server",
									"Failed to communicate with the server. ");

						}
					});
		} else if (type.equals("Form")) {
			if (itemId != null) {
				ModalOverlay.show();
				rpcService.fetchConfigObject(objectName, itemId, type, name,
						new AsyncCallback<FormObject>() {

							@Override
							public void onFailure(Throwable caught) {
								ModalOverlay.hide();
								InfoPanel
										.show("Server",
												"Failed to communicate with the server. ");
							}

							@Override
							public void onSuccess(FormObject result) {
								ModalOverlay.hide();
								display.setForm(formGenerator
										.generateForm(result));
								formGenerator.getFirst().setFocus(true);
							}

						});
			} else {
				ModalOverlay.show();
				rpcService.parseConfigObject(Cookies.getCookie("username"),
						objectName, type, name,
						new AsyncCallback<FormObject>() {

							@Override
							public void onSuccess(FormObject result) {
								display.setForm(formGenerator
										.generateForm(result));
								formGenerator.getFirst().setFocus(true);
								ModalOverlay.hide();

							}

							@Override
							public void onFailure(Throwable caught) {
								ModalOverlay.hide();
								InfoPanel
										.show("Server",
												"Failed to communicate with the server. ");
							}
						});
			}

		} else if (type.equals("List")) {
			table = new CustomPagingScrollTable();
			table.setType(CustomPagingScrollTable.BOTH);
			table.setInitialUse(true);
			table.setRpcService(rpcService);
			table.setUsername(Cookies.getCookie("username"));
			table.setObjectName(objectName);
			table.setObjectType(type);
			table.setName(name);
			table.getTable().setHeight("350px");
			table.fillTable();
			display.getContent().add(table);
			table.addActionEventHandler(new ActionEventHandler() {

				@Override
				public void onEdit(ActionEvent event) {
					switch (event.getAction()) {
					case ActionEvent.EDIT:
						String name = "";
						if(History.getToken().split("/").length>2)
							name = History.getToken().split("/")[2];
						EditPresenter editPresenter = new EditPresenter(rpcService, eventBus, new EditView("Edit", objectName), "Edit", objectName,
								event.getId(), name);
						editPresenter.getFormGenerator().addEditEvent(new EditEventHandler() {
							@Override
							public void onEdit(EditEvent event) {
								table.fillTable();
							}
						});
						editPresenter.go(editPresenter.getDisplay().getWindow());
						break;
					case ActionEvent.SELECT:
						MessageBox.info("", event.getId());
						break;
					case ActionEvent.DELETE:
						deleteEntry(objectName, event.getId());
						break;
					case ActionEvent.DELETE_ALL:
						deleteEntries(objectName, event.getIds());
						break;
					}
				}
			});
		}
	}

	public void deleteEntry(final String type, String id) {

		final ArrayList<String> ids = new ArrayList<String>();
		ids.add(id);

		MessageBox
				.confirm(
						"Delete entry",
						"You are about to delete "
								+ ids.get(0)
								+ ". Press OK to confirm or Cancel to cancel and close this prompt.",
						new ConfirmationCallback() {

							@Override
							public void onResult(boolean result) {
								if (result == true) {
									ModalOverlay.show();

									rpcService.deleteObject(type, ids,
											new AsyncCallback<Boolean>() {

												@Override
												public void onFailure(
														Throwable caught) {
													ModalOverlay.hide();
													InfoPanel
															.show("Server",
																	"Failed to communicate with the server. ");
												}

												@Override
												public void onSuccess(
														Boolean result) {
													ModalOverlay.hide();
													InfoPanel.show("Server",
															"Entry deleted.");
													table.fillTable();
												}
												
											});
								}
							}
						});
	}

	public void deleteEntries(final String type, final ArrayList<String> ids) {
		String idList = "";
		for (String id : ids) {
			idList += id + ", ";
		}
		MessageBox
				.confirm(
						"Delete entry",
						"You are about to delete multiple entries: "
								+ idList.substring(0, idList.length() - 2)
								+ ". Press OK to confirm or Cancel to cancel and close this prompt.",
						new ConfirmationCallback() {

							@Override
							public void onResult(boolean result) {
								if (result == true) {
									ModalOverlay.show();
									rpcService.deleteObject(type, ids,
											new AsyncCallback<Boolean>() {

												@Override
												public void onFailure(
														Throwable caught) {
													ModalOverlay.hide();
													InfoPanel
															.show("Server",
																	"Failed to communicate with the server. ");
												}

												@Override
												public void onSuccess(
														Boolean result) {
													ModalOverlay.hide();
													InfoPanel.show("Server",
															"Entries deleted.");
													table.fillTable();
												}

											});
								}
							}

						});

	}
}
